home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / containerhandle_shared.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  11.0 KB  |  344 lines

  1. // -*- c++ -*-
  2. #ifndef _GLIBMM_CONTAINERHANDLE_SHARED_H
  3. #define _GLIBMM_CONTAINERHANDLE_SHARED_H
  4.  
  5. /* $Id: containerhandle_shared.h,v 1.11 2005/01/21 19:26:04 murrayc Exp $ */
  6.  
  7. /* Copyright (C) 2002 The gtkmm Development Team
  8.  *
  9.  * This library is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Library General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2 of the License, or (at your option) any later version.
  13.  *
  14.  * This library is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Library General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Library General Public
  20.  * License along with this library; if not, write to the Free
  21.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include <cstddef>
  25. #include <algorithm>
  26. #include <iterator>
  27. #include <vector>
  28. #include <deque>
  29. #include <list>
  30.  
  31. #include <glib-object.h>
  32. #include <glib/gmem.h>
  33. #include <glibmm/refptr.h>
  34. #include <glibmm/ustring.h>
  35. #include <glibmm/wrap.h>
  36. #include <glibmm/debug.h>
  37.  
  38. #include <glibmmconfig.h>
  39. GLIBMM_USING_STD(forward_iterator_tag)
  40. GLIBMM_USING_STD(random_access_iterator_tag)
  41. GLIBMM_USING_STD(distance)
  42. GLIBMM_USING_STD(copy)
  43. GLIBMM_USING_STD(vector)
  44. GLIBMM_USING_STD(deque)
  45. GLIBMM_USING_STD(list)
  46.  
  47.  
  48. namespace Glib
  49. {
  50.  
  51. /** @defgroup ContHandles Generic container converters
  52.  */
  53.  
  54. /**
  55.  * @ingroup ContHandles
  56.  */
  57. enum OwnershipType
  58. {
  59.   OWNERSHIP_NONE = 0,
  60.   OWNERSHIP_SHALLOW, //Release the list, but not its elements, when the container is deleted
  61.   OWNERSHIP_DEEP //Release the list, and its elements, when the container is deleted.
  62. };
  63.  
  64.  
  65. /** Utility class holding an iterator sequence.
  66.  * @ingroup ContHandles
  67.  * This can be used to initialize a Glib container handle (such as
  68.  * Glib::ArrayHandle) with an iterator sequence.  Use the helper
  69.  * function Glib::sequence() to create a Sequence<> object.
  70.  */
  71. template <class Iterator>
  72. class Sequence
  73. {
  74. private:
  75.   Iterator pbegin_;
  76.   Iterator pend_;
  77.  
  78. public:
  79.   Sequence(Iterator pbegin, Iterator pend)
  80.     : pbegin_(pbegin), pend_(pend) {}
  81.  
  82.   Iterator begin() const { return pbegin_; }
  83.   Iterator end()   const { return pend_;   }
  84.   size_t   size()  const { return std::distance(pbegin_, pend_); }
  85. };
  86.  
  87. /** Helper function to create a Glib::Sequence<> object, which
  88.  * in turn can be used to initialize a container handle.
  89.  * @ingroup ContHandles
  90.  *
  91.  * @par Usage example:
  92.  * @code
  93.  * combo.set_popdown_strings(Glib::sequence(foo_begin, foo_end));
  94.  * @endcode
  95.  */
  96. template <class Iterator> inline
  97. Sequence<Iterator> sequence(Iterator pbegin, Iterator pend)
  98. {
  99.   return Sequence<Iterator>(pbegin, pend);
  100. }
  101.  
  102.  
  103. namespace Container_Helpers
  104. {
  105.  
  106. /** @defgroup ContHelpers Helper classes
  107.  * @ingroup ContHandles
  108.  */
  109.  
  110. /** Generic TypeTraits implementation.
  111.  * @ingroup ContHelpers
  112.  * This can be used if the C++ type is the same as the C type, or if implicit
  113.  * conversions between the types are available.  Also, the types are required
  114.  * to implement copy-by-value semantics.  (Ownership is just ignored.)
  115.  */
  116. template <class T>
  117. struct TypeTraits
  118. {
  119.   typedef T CppType;
  120.   typedef T CType;
  121.   typedef T CTypeNonConst;
  122.  
  123.   static CType   to_c_type      (const CppType& item) { return item; }
  124.   static CppType to_cpp_type    (const CType&   item) { return item; }
  125.   static void    release_c_type (const CType&)        {}
  126. };
  127.  
  128. #ifndef DOXYGEN_SHOULD_SKIP_THIS /* hide the specializations */
  129.  
  130. //For some (proably, more spec-compliant) compilers, these specializations must
  131. //be next to the objects that they use.
  132. #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
  133.  
  134. /** Partial specialization for pointers to GtkObject instances.
  135.  * @ingroup ContHelpers
  136.  */
  137. template <class T>
  138. struct TypeTraits<T*>
  139. {
  140.   typedef T *                          CppType;
  141.   typedef typename T::BaseObjectType * CType;
  142.   typedef typename T::BaseObjectType * CTypeNonConst;
  143.  
  144.   static CType   to_c_type      (CppType ptr) { return Glib::unwrap(ptr);      }
  145.   static CType   to_c_type      (CType   ptr) { return ptr;                    }
  146.   static CppType to_cpp_type    (CType   ptr)
  147.   {
  148.     //We copy/paste the widget wrap() implementation here,
  149.     //because we can not use a specific Glib::wrap(T_Impl) overload here,
  150.     //because that would be "dependent", and g++ 3.4 does not allow that.
  151.     //The specific Glib::wrap() overloads don't do anything special anyway.
  152.     GObject* cobj = (GObject*)ptr;
  153.     return dynamic_cast<CppType>(Glib::wrap_auto(cobj, false /* take_copy */));
  154.   }
  155.   
  156.   static void    release_c_type (CType   ptr)
  157.   {
  158.     GLIBMM_DEBUG_UNREFERENCE(0, ptr);
  159.     g_object_unref(ptr);
  160.   }
  161. };
  162.  
  163. //This confuse the SUN Forte compiler, so we ifdef it out:
  164. #ifdef GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS 
  165.  
  166. /** Partial specialization for pointers to const GtkObject instances.
  167.  * @ingroup ContHelpers
  168.  */
  169. template <class T>
  170. struct TypeTraits<const T*>
  171. {
  172.   typedef const T *                          CppType;
  173.   typedef const typename T::BaseObjectType * CType;
  174.   typedef typename T::BaseObjectType *       CTypeNonConst;
  175.  
  176.   static CType   to_c_type      (CppType ptr) { return Glib::unwrap(ptr);      }
  177.   static CType   to_c_type      (CType   ptr) { return ptr;                    }
  178.   static CppType to_cpp_type    (CType   ptr)
  179.   {
  180.      //We copy/paste the widget wrap() implementation here,
  181.      //because we can not use a specific Glib::wrap(T_Impl) overload here,
  182.      //because that would be "dependent", and g++ 3.4 does not allow that.
  183.      //The specific Glib::wrap() overloads don't do anything special anyway.
  184.      GObject* cobj = (GObject*)const_cast<CTypeNonConst>(ptr);
  185.      return dynamic_cast<CppType>(Glib::wrap_auto(cobj, false /* take_copy */));
  186.   }
  187.   
  188.   static void    release_c_type (CType   ptr)
  189.   {
  190.     GLIBMM_DEBUG_UNREFERENCE(0, ptr);
  191.     g_object_unref(const_cast<CTypeNonConst>(ptr));
  192.   }
  193. };
  194. #endif //GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
  195.  
  196. /** Partial specialization for pointers to GObject instances.
  197.  * @ingroup ContHelpers
  198.  * The C++ type is always a Glib::RefPtr<>.
  199.  */
  200. template <class T>
  201. struct TypeTraits< Glib::RefPtr<T> >
  202. {
  203.   typedef Glib::RefPtr<T>              CppType;
  204.   typedef typename T::BaseObjectType * CType;
  205.   typedef typename T::BaseObjectType * CTypeNonConst;
  206.  
  207.   static CType   to_c_type      (const CppType& ptr) { return Glib::unwrap(ptr);     }
  208.   static CType   to_c_type      (CType          ptr) { return ptr;                   }
  209.   static CppType to_cpp_type    (CType          ptr)
  210.   {
  211.     //return Glib::wrap(ptr, true);
  212.  
  213.     //We copy/paste the wrap() implementation here,
  214.     //because we can not use a specific Glib::wrap(CType) overload here,
  215.     //because that would be "dependent", and g++ 3.4 does not allow that.
  216.     //The specific Glib::wrap() overloads don't do anything special anyway.
  217.     GObject* cobj = (GObject*)const_cast<CTypeNonConst>(ptr);
  218.     return Glib::RefPtr<T>( dynamic_cast<T*>(Glib::wrap_auto(cobj, true /* take_copy */)) );
  219.     //We use dynamic_cast<> in case of multiple inheritance.
  220.   }
  221.   
  222.   static void    release_c_type (CType          ptr)
  223.   {
  224.     GLIBMM_DEBUG_UNREFERENCE(0, ptr);
  225.     g_object_unref(ptr);
  226.   }
  227. };
  228.  
  229. //This confuse the SUN Forte compiler, so we ifdef it out:
  230. #ifdef GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
  231.  
  232. /** Partial specialization for pointers to const GObject instances.
  233.  * @ingroup ContHelpers
  234.  * The C++ type is always a Glib::RefPtr<>.
  235.  */
  236. template <class T>
  237. struct TypeTraits< Glib::RefPtr<const T> >
  238. {
  239.   typedef Glib::RefPtr<const T>              CppType;
  240.   typedef const typename T::BaseObjectType * CType;
  241.   typedef typename T::BaseObjectType *       CTypeNonConst;
  242.  
  243.   static CType   to_c_type      (const CppType& ptr) { return Glib::unwrap(ptr);     }
  244.   static CType   to_c_type      (CType          ptr) { return ptr;                   }
  245.   static CppType to_cpp_type    (CType          ptr)
  246.   {
  247.     //return Glib::wrap(ptr, true);
  248.  
  249.     //We copy/paste the wrap() implementation here,
  250.     //because we can not use a specific Glib::wrap(CType) overload here,
  251.     //because that would be "dependent", and g++ 3.4 does not allow that.
  252.     //The specific Glib::wrap() overloads don't do anything special anyway.
  253.     GObject* cobj = (GObject*)(ptr);
  254.     return Glib::RefPtr<const T>( dynamic_cast<const T*>(Glib::wrap_auto(cobj, true /* take_copy */)) );
  255.     //We use dynamic_cast<> in case of multiple inheritance.
  256.   }
  257.   
  258.   static void    release_c_type (CType          ptr)
  259.   {
  260.     GLIBMM_DEBUG_UNREFERENCE(0, ptr);
  261.     g_object_unref(const_cast<CTypeNonConst>(ptr));
  262.   }
  263. };
  264.  
  265. #endif //GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
  266.  
  267. #endif //GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
  268.  
  269. /** Specialization for UTF-8 strings.
  270.  * @ingroup ContHelpers
  271.  * When converting from C++ to C, Glib::ustring will be accepted as well as
  272.  * std::string and 'const char*'.  However, when converting to the C++ side,
  273.  * the output type cannot be 'const char*'.
  274.  */
  275. template <>
  276. struct TypeTraits<Glib::ustring>
  277. {
  278.   typedef Glib::ustring CppType;
  279.   typedef const char *  CType;
  280.   typedef char *        CTypeNonConst;
  281.  
  282.   static CType to_c_type (const Glib::ustring& str) { return str.c_str(); }
  283.   static CType to_c_type (const std::string&   str) { return str.c_str(); }
  284.   static CType to_c_type (CType                str) { return str;         }
  285.  
  286.   static CppType to_cpp_type(CType str)
  287.     { return (str) ? Glib::ustring(str) : Glib::ustring(); }
  288.  
  289.   static void release_c_type(CType str)
  290.     { g_free(const_cast<CTypeNonConst>(str)); }
  291. };
  292.  
  293. /** Specialization for std::string.
  294.  * @ingroup ContHelpers
  295.  * When converting from C++ to C, std::string will be accepted as well as
  296.  * 'const char*'.  However, when converting to the C++ side, the output type
  297.  * cannot be 'const char*'.
  298.  */
  299. template <>
  300. struct TypeTraits<std::string>
  301. {
  302.   typedef std::string   CppType;
  303.   typedef const char *  CType;
  304.   typedef char *        CTypeNonConst;
  305.  
  306.   static CType to_c_type (const std::string&   str) { return str.c_str(); }
  307.   static CType to_c_type (const Glib::ustring& str) { return str.c_str(); }
  308.   static CType to_c_type (CType                str) { return str;         }
  309.  
  310.   static CppType to_cpp_type(CType str)
  311.     { return (str) ? std::string(str) : std::string(); }
  312.  
  313.   static void release_c_type(CType str)
  314.     { g_free(const_cast<CTypeNonConst>(str)); }
  315. };
  316.  
  317. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  318.  
  319.  
  320. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  321. #ifndef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  322.  
  323. /* The STL containers in Sun's libCstd don't support templated sequence
  324.  * constructors, for "backward compatibility" reasons.  This helper function
  325.  * is used in the ContainerHandle -> STL-container conversion workarounds.
  326.  */
  327. template <class Cont, class In>
  328. void fill_container(Cont& container, In pbegin, In pend)
  329. {
  330.   for(; pbegin != pend; ++pbegin)
  331.     container.push_back(*pbegin);
  332. }
  333.  
  334. #endif /* GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS */
  335. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  336.  
  337. } // namespace Container_Helpers
  338.  
  339. } // namespace Glib
  340.  
  341.  
  342. #endif /* _GLIBMM_CONTAINERHANDLE_SHARED_H */
  343.  
  344.